package com.sys.platform.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson2.JSONObject;
import com.sys.platform.common.socket.WebSocket;
import com.sys.platform.common.socket.WebSocketDTO;
import com.sys.platform.common.utils.StringUtils;
import com.sys.platform.entity.*;
import com.sys.platform.entity.request.Notice.NoticeRequestDTO;
import com.sys.platform.entity.request.dossierDeviceWarning.DossierDeviceWarningInfoDTO;
import com.sys.platform.entity.vo.SysUserVO;
import com.sys.platform.entity.vo.dossierDeviceWarning.DossierDeviceWarningVO;
import com.sys.platform.mapper.*;
import com.sys.platform.service.IDossierDeviceWarningService;
import com.sys.platform.service.IVoiceNoticeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 档案馆设备告警Service业务层处理
 *
 * @author yuanfuqiang
 * @date 2024-01-10
 */
@Slf4j
@Service
public class DossierDeviceWarningServiceImpl implements IDossierDeviceWarningService {

    @Autowired
    private DossierDeviceWarningMapper dossierDeviceWarningMapper;

    @Autowired
    private SysDictDataMapper dictDataMapper;

    @Autowired
    private DossierDeviceMapper dossierDeviceMapper;

    @Autowired
    private IVoiceNoticeService voiceNoticeService;

    @Autowired
    private DossierWarningUserMapper dossierWarningUserMapper;

    @Autowired
    private SysUserMapper userMapper;

    /**
     * 查询档案馆设备告警列表
     *
     * @param dossierDeviceWarning 档案馆设备告警
     * @return 档案馆设备告警
     */
    @Override
    public List<DossierDeviceWarningVO> selectDossierDeviceWarningList(DossierDeviceWarningVO dossierDeviceWarning) {
        return dossierDeviceWarningMapper.selectDossierDeviceWarningList(dossierDeviceWarning);
    }

    /**
     * 新增档案馆设备告警
     *
     * @param dossierDeviceWarning 档案馆设备告警
     * @return 结果
     */
    @Override
    public void insertDossierDeviceWarning(DossierDeviceWarning dossierDeviceWarning, HttpServletRequest request) {

        SysDictData dictData = new SysDictData();
        dictData.setDictType("humiture");
        List<SysDictData> dictDataList = dictDataMapper.select(dictData);
        List<String> stringList = new ArrayList<>();
        int warningStatus = 1; //0正常 1异常
        int status = 0; //0待处理 1已完结
        if (dossierDeviceWarning.getType() == 2) {
            //温湿度告警
            double temperature = Double.parseDouble(dictDataList.get(0).getDictValue()); //温度
            double humidity = Double.parseDouble(dictDataList.get(1).getDictValue());  //湿度
            double wd = Double.parseDouble(dossierDeviceWarning.getData().split(",")[0]) / 10;
            double sd = Double.parseDouble(dossierDeviceWarning.getData().split(",")[1]) / 10;
            log.info("温度：{}，湿度：{}", wd >= temperature ? "正常" : wd + "，异常", sd <= humidity ? "正常" : sd + "，异常");
            stringList.add(String.valueOf(wd));
            stringList.add(String.valueOf(sd));
            if (wd >= temperature && sd <= humidity) {
                warningStatus = 0;
                status = 1;
            }
        } else {
            //1.人员入侵，3.漏水检测 0正常 1告警
            String warningVal = dictDataList.get(2).getDictValue(); // 0正常 1告警
            if (dossierDeviceWarning.getData().equals(warningVal)) {
                warningStatus = 0;
                status = 1;
            }
        }

        dossierDeviceWarning.setStatus(status);
        dossierDeviceWarning.setWarningStatus(warningStatus);
        if (dossierDeviceWarning.getData().contains(",")) {
            dossierDeviceWarning.setData(String.join(",", stringList));
        }

        //去重
        DossierDeviceWarning warning = new DossierDeviceWarning();
        warning.setType(dossierDeviceWarning.getType());
        warning.setDeviceId(dossierDeviceWarning.getDeviceId());
        warning.setWarningStatus(dossierDeviceWarning.getWarningStatus());
        DossierDeviceWarningVO vo = dossierDeviceWarningMapper.selectDossierDeviceWarningListTop1(warning);
        if (StringUtils.isNull(vo)) {
            dossierDeviceWarning.setCreateTime(DateTime.now());
            int i = dossierDeviceWarningMapper.insertSelective(dossierDeviceWarning);
        } else {
            dossierDeviceWarning.setId(vo.getId());
            dossierDeviceWarning.setUpdateTime(DateTime.now());
            dossierDeviceWarningMapper.updateByPrimaryKeySelective(dossierDeviceWarning);
        }

        //自动维护到设备表
        DossierDevice dossierDevice = new DossierDevice();
        dossierDevice.setDeviceId(dossierDeviceWarning.getDeviceId());
        dossierDevice.setType(dossierDeviceWarning.getType());
        List<DossierDevice> dossierDeviceList = dossierDeviceMapper.select(dossierDevice);
        if (dossierDeviceList.size() == 0) {
            dossierDevice.setStatus(1);
            dossierDevice.setIpAddress(request.getLocalAddr());
            dossierDevice.setCreateTime(DateTime.now());
            dossierDeviceMapper.insert(dossierDevice);
        }

        //WebSocket数据推送
        WebSocketDTO dto = new WebSocketDTO();
        dto.setMsg(JSONObject.toJSONString(dossierDeviceWarning));
        WebSocket.sendMessageTo(dto);

        //异常告警发送短信
        if (warningStatus == 1) {
            log.info("档案馆设备异常告警发送短信");
            sendSMS(dossierDeviceWarning);
        }

        return;
    }

    public void sendSMS(DossierDeviceWarning dossierDeviceWarning) {
        List<Long> warningUserList = dossierWarningUserMapper.selectAll().stream().map(DossierWarningUser::getUserId).collect(Collectors.toList());
        if (warningUserList.size() == 0) {
            return;
        }
        List<String> phoneNumberList = userMapper.selectByIds(warningUserList).stream().map(SysUser::getPhonenumber).collect(Collectors.toList());
        phoneNumberList.stream().filter(item -> item.length() > 0);
        //自动电话通知
        NoticeRequestDTO noticeRequestDTO = new NoticeRequestDTO();
        noticeRequestDTO.setNoticeContent("档案馆设备id：" + dossierDeviceWarning.getDeviceId() + ",类型为：" + dossierDeviceWarning.getType() + "产生告警");
        noticeRequestDTO.setNoticeType(NoticeRequestDTO.NoticeTypeEnum.Call.name());
        noticeRequestDTO.setPhoneNumber(phoneNumberList);
        CompletableFuture.runAsync(() -> voiceNoticeService.sendSmsOrCallNotice(noticeRequestDTO));
        log.error("语音电话发送成功，手机号:" + phoneNumberList);

        //发送短信通知
        noticeRequestDTO.setNoticeContent("档案馆设备id：" + dossierDeviceWarning.getDeviceId() + ",类型为：" + dossierDeviceWarning.getType() + "产生告警");
        noticeRequestDTO.setNoticeType(NoticeRequestDTO.NoticeTypeEnum.SMS.name());
        noticeRequestDTO.setPhoneNumber(phoneNumberList);
        CompletableFuture.runAsync(() -> voiceNoticeService.sendSmsOrCallNotice(noticeRequestDTO));

    }

    /**
     * 修改档案馆设备告警
     *
     * @param dossierDeviceWarning 档案馆设备告警
     * @return 结果
     */
    @Override
    public int updateDossierDeviceWarning(DossierDeviceWarning dossierDeviceWarning) {
        dossierDeviceWarning.setStatus(1);
        dossierDeviceWarning.setCompleteTime(new Date());
        dossierDeviceWarning.setUpdateTime(DateTime.now());
        int i = dossierDeviceWarningMapper.updateByPrimaryKeySelective(dossierDeviceWarning);
        if (i > 0) {
            WebSocketDTO dto = new WebSocketDTO();
            dto.setMsg("refreshDossierDeviceWarningList");
            WebSocket.sendMessageTo(dto);
        }
        return i;
    }

    /**
     * 批量删除档案馆设备告警
     *
     * @param ids 需要删除的档案馆设备告警主键
     * @return 结果
     */
    @Override
    public int deleteDossierDeviceWarningByIds(Long[] ids) {
        AtomicInteger i = new AtomicInteger();
        Arrays.stream(ids).forEach(id -> {
            dossierDeviceWarningMapper.deleteByPrimaryKey(id);
            i.set(1);
        });
        return i.get();
    }

    @Override
    public void insertDossierWarningUserId(Long[] userId) {
        Arrays.stream(userId).forEach(id -> {
            DossierWarningUser dossierWarningUser = new DossierWarningUser();
            dossierWarningUser.setUserId(id);
            List<DossierWarningUser> userList = dossierWarningUserMapper.select(dossierWarningUser);
            if (userList.size() == 0) {
                dossierWarningUser.setCreateTime(DateTime.now());
                dossierWarningUserMapper.insertSelective(dossierWarningUser);
            }
        });

    }

    @Override
    public int deleteDossierWarningByIds(Long[] ids) {
        AtomicInteger i = new AtomicInteger();
        Arrays.stream(ids).forEach(id -> {
            dossierWarningUserMapper.deleteByPrimaryKey(id);
            i.set(1);
        });
        return i.get();
    }

    @Override
    public List<SysUserVO> selectUserList() {
        return dossierWarningUserMapper.selectUserList();
    }

    @Override
    public List<SysUserVO> userList() {
        return dossierWarningUserMapper.userList();
    }

    /**
     * 设备告警详情
     *
     * @param dto
     * @return
     */
    @Override
    public DossierDeviceWarningVO selectDossierDeviceWarningInfo(DossierDeviceWarningInfoDTO dto) {
        return dossierWarningUserMapper.selectDossierDeviceWarningInfo(dto);
    }

}
